import { GeographyQuery, GeographyService } from "@mallfoundry/geography"
import { Store, StoreProgress, StoreService } from "@mallfoundry/store"
import { Button, Cascader, Checkbox, Divider, Form, Input } from "antd"
import { CascaderOptionType } from "antd/lib/cascader"
import * as _ from "lodash"
import * as React from "react"
import { useEffect, useState } from "react"
import { useHistory } from "react-router-dom"
import Page from "../../components/page"
import { messageError } from "../../utils/reason"
import classes from "./store-create.module.scss"

enum DivisionType {
  Province, City, County
}

class AddressOption {
  public value: string = ""
  public label: string = ""
  public isLeaf: boolean = false
  public division?: DivisionType
  public children: AddressOption[] = []
}


const DEFAULT_COUNTRY_ID = "1"

export default function StoreCreate() {
  const history = useHistory()
  const [storeCreating, setStoreCreating] = useState(false)
  const [addressOptions, setAddressOptions] = useState([] as AddressOption[])

  const layout = {
    labelCol: { span: 6 },
    wrapperCol: { span: 12 },
  }

  const noLabelLayout = {
    wrapperCol: { offset: 6, span: 12 },
  }

  const tailLayout = {
    wrapperCol: { offset: 6, span: 16 },
  }

  useEffect(() => {
    GeographyService.getProvinces(new GeographyQuery()
      .toBuilder()
      .countryId(DEFAULT_COUNTRY_ID)
      .build())
      .then(aProvinces => _.map(aProvinces, aProvince => _.assign(new AddressOption(), {
        value: aProvince.id,
        label: aProvince.name,
        isLeaf: false,
        division: DivisionType.Province,
        children: undefined,
      })))
      .then(setAddressOptions)
  }, [])

  function loadAddressOptions(selectedOptions?: CascaderOptionType[]) {
    console.log(selectedOptions)
    if (_.isUndefined(selectedOptions)) {
      return
    }
    const targetOption = selectedOptions[selectedOptions.length - 1]
    if (targetOption["division"] === DivisionType.Province) {
      targetOption.loading = true
      GeographyService.getCities(new GeographyQuery().toBuilder()
        .countryId(DEFAULT_COUNTRY_ID)
        .provinceId(targetOption.value as string)
        .scope(2)
        .build())
        .then(aCities => _.map(aCities, aCity => _.assign(new AddressOption(), {
          value: aCity.id,
          label: aCity.name,
          isLeaf: false,
          division: DivisionType.City,
          children: _.map(aCity.counties, aCounty => _.assign(new AddressOption(), {
            value: aCounty.id,
            label: aCounty.name,
            isLeaf: true,
            division: DivisionType.County,
          })),
        })))
        .then(aOptions => targetOption.children = aOptions)
        .then(() => targetOption.loading = false)
        .then(() => setAddressOptions([...addressOptions]))
    }
  }

  function createStoreAddress(location: [string, string, string]) {
    const province = _.find(addressOptions, aProvince => aProvince.value === location[0]) as unknown as AddressOption
    const city = _.find(province.children, aCity => aCity.value === location[1]) as unknown as AddressOption
    const county = _.find(city.children, aCounty => aCounty.value === location[2]) as unknown as AddressOption
    return {
      countryCode: "+86",
      provinceId: province.value,
      province: province.label,
      cityId: city.value,
      city: city.label,
      countyId: county.value,
      county: county.label,
    }
  }

  function fetchStoreInitializing(newStore: Store): Promise<Store> {
    const { id: storeId = "" } = newStore
    return StoreService
      .getStoreProgress(storeId)
      .then(initializing => {
        if (initializing.state === StoreProgress.ProgressState.New
          || initializing.state === StoreProgress.ProgressState.Initializing) {
          return new Promise((resolve, reject) => {
            const timeoutId = setTimeout(() => {
              fetchStoreInitializing(newStore)
                .then(resolve).catch(reject)
                .finally(() => clearTimeout(timeoutId))
            }, 500)
          })
        } else {
          return newStore
        }
      })
  }

  function onFinish(values: any) {
    const aStore = _.assign(new Store(), {
      id: values.id,
      name: values.name,
      industry: values.industry,
      address: values.address,
    }, createStoreAddress(values.location))
    setStoreCreating(true)
    StoreService
      .createStore(aStore)
      .then(newStore => StoreService
        .initializeStore(newStore.id as string)
        .then(() => newStore))
      .then(fetchStoreInitializing)
      .then(newStore => {
        setStoreCreating(false)
        history.push(`/stores/${newStore.id}/dashboard`)
      })
      .catch(r => {
        setStoreCreating(false)
        messageError(r)
      })
  }

  return (<div className={classes.root}>
    <Page.Header title="创建店铺" ghost={false}/>
    <Divider/>
    <Page.Content className={classes.content}>
      <Form   {...layout} size="large" name="createStore" onFinish={onFinish}>
        <Form.Item label="主营类目" name="industry"
                   rules={[{ required: true, message: "请填写主营类目" }]}>
          <Input placeholder="请填写主营类目"/>
        </Form.Item>
        <Form.Item label="店铺名称" name="name"
                   rules={[{ required: true, message: "请填写店铺名称" }]}>
          <Input placeholder="请填写店铺名称"/>
        </Form.Item>
        <Form.Item noStyle>
          <Form.Item name="location" label="店铺地址" {...layout}
                     rules={[{ required: true, message: "请选择店铺地址" }]}>
            <Cascader popupClassName={classes.storeLocation}
                      placeholder="请选择店铺地址" allowClear={false}
                      options={addressOptions} loadData={loadAddressOptions}/>
          </Form.Item>
          <Form.Item name="address" {...noLabelLayout}
                     rules={[{ required: true, message: "请填写店铺详细地址" }]}>
            <Input placeholder="请填写店铺详细地址"/>
          </Form.Item>
        </Form.Item>
        <Form.Item name="agree" valuePropName="checked" {...tailLayout}
                   rules={[{ required: true, message: "请同意商城软件服务协议" }]}>
          <Checkbox>我已阅读并同意《商城软件服务协议》</Checkbox>
        </Form.Item>
        <Form.Item {...tailLayout}>
          <Button className={classes.createStoreButton}
                  loading={storeCreating}
                  type="primary" htmlType="submit">创建店铺</Button>
        </Form.Item>
      </Form>
    </Page.Content>
  </div>)
}
